package com.mengxin.cloud.controller;

import com.mengxin.cloud.message.req.WebDavDownLoadFileReq;
import com.mengxin.cloud.message.req.WebDavUploadFileReq;
import com.mengxin.cloud.message.resp.WebDavDownLoadFileResp;
import com.mengxin.cloud.message.resp.WebDavUploadFileResp;
import com.mengxin.cloud.util.AESUtils;
import com.mengxin.cloud.util.EncrypDES;
import com.mengxin.cloud.util.FileSplitUtils;
import com.googlecode.sardine.DavResource;
import com.googlecode.sardine.Sardine;
import com.googlecode.sardine.SardineFactory;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Admin
 */
@Slf4j
@RestController()
@RequestMapping(value = "/webdav")
public class WebDavController {

    @Value("${WebDav.userName}")
    private String userName;
    @Value("${WebDav.passWord}")
    private String passWord;
    @Value("${WebDav.server}")
    private String server;
    @Value("${WebDav.key}")
    private String key;

    @PostMapping("/upload")
    @ApiOperation(value = "上传", notes = "上传")
    @ApiImplicitParam(name = "req", value = "上传", required = true, dataType = "WebDavUploadFileReq")
    public WebDavUploadFileResp uploadFile(@RequestBody WebDavUploadFileReq req){
        WebDavUploadFileResp resp = new WebDavUploadFileResp();
        String path = req.getPath();
        File file = new File(path);
        if(!file.exists()){
            log.error("文件不存在："+path);
            resp.setMessage("文件不存在："+path);
            return resp;
        }
        StringBuilder builder = new StringBuilder(server).append("test/");
        InputStream inputStream = null;
        try {
            Sardine sardine = SardineFactory.begin(userName, passWord);
            //加密
            EncrypDES encrypDES = new EncrypDES();
            String base64Name = encrypDES.encrypt(file.getName());
            builder.append(base64Name).append("/");
            //创建云文件存放地址
            if(sardine.exists(builder.toString())){
                log.info( builder.toString() + " is exists");
                sardine.delete(builder.toString());
            }
            sardine.createDirectory(builder.toString());
            //创建分割文件存放目录
            StringBuilder parentURL = new StringBuilder(file.getParentFile().getPath());
            parentURL.append("\\").append(file.getName()).append("part");
            File partFile = new File(parentURL.toString());
            if(partFile.exists()){
                partFile.delete();
            }
            partFile.mkdirs();
            //文件分割
            List<File> filePartList = FileSplitUtils.split(file,parentURL.toString());
            List<File> destFilePartList = new ArrayList<>();
            //文件加密
            for(File toWebDavFile:filePartList){
                String partFileName = toWebDavFile.getPath();
                String destPartFileName = partFileName+"dest";
                AESUtils.encryptFile(key,partFileName,destPartFileName);
                //删除源文件
                toWebDavFile.delete();
                destFilePartList.add(new File(destPartFileName));
            }
            //文件上传
            for(File toWebDavFile:destFilePartList){
                inputStream = new FileInputStream(toWebDavFile);
                String toWebDavFileUrl = builder.toString()+toWebDavFile.getName();
                sardine.put(toWebDavFileUrl,inputStream);
                toWebDavFile.delete();
                inputStream.close();
            }
            resp.setCode(base64Name);
            resp.setMessage("success");
        } catch (Exception e) {
            log.error(e.getMessage());
            resp.setMessage("fail :"+e.getMessage());
        } finally {
            if(inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    log.error(e.getMessage());
                }
            }
        }
        return resp;
    }

    @PostMapping("/download")
    @ApiOperation(value = "下载", notes = "下载")
    @ApiImplicitParam(name = "req", value = "下载", required = true, dataType = "WebDavDownLoadFileReq")
    public WebDavDownLoadFileResp downLoadFile(@RequestBody WebDavDownLoadFileReq req) throws Exception {
        WebDavDownLoadFileResp resp = new WebDavDownLoadFileResp();
        String path = req.getPath();
        String code = req.getCode();
        EncrypDES encrypDES = new EncrypDES();
        String fileName = encrypDES.decrypt(code);
        File destFile = new File(path+fileName);
        if(destFile.exists()){
            destFile.delete();
        }
        destFile.createNewFile();
        StringBuilder builder = new StringBuilder(server).append("test/");
        builder.append(code);
        try {
            Sardine sardine = SardineFactory.begin(userName, passWord);
            if(!sardine.exists(builder.toString())){
                resp.setMessage("File is not exist!");
                return resp;
            }
            builder.append("/");
            //下载文件
            List<DavResource>  davResourceList = sardine.getResources(builder.toString());
            List<File> fromWebDavFileList = new ArrayList<>();
            String partPath = path+"part\\";
            File partParentFile = new File(partPath);
            if(partParentFile.exists()){
                partParentFile.delete();
            }
            partParentFile.mkdirs();
            for(DavResource davResource:davResourceList){
                String partUrl = partPath;
                if(davResource.isCurrentDirectory()){
                    continue;
                }
                InputStream fromWebDavInputStream =sardine.getInputStream(davResource.getAbsoluteUrl());
                partUrl += davResource.getName();
                File partFile = new File(partUrl);
                if(partFile.exists()){
                    partFile.delete();
                }
                partFile.createNewFile();
                //加密文件写入本地
                writeToLocal(partUrl,fromWebDavInputStream);
                //解密
                String url = partUrl.substring(0,partUrl.length()-4);
                AESUtils.decryptFile(key,partUrl,url);
                fromWebDavFileList.add(new File(url));
                partFile.delete();
            }
            //聚合文件
            FileSplitUtils.combinateFormChips(path+"part\\",destFile);
            for(File file: fromWebDavFileList){
                file.delete();
            }
            partParentFile.delete();
            resp.setMessage("success");
        } catch (Exception e) {
            log.error(e.getMessage());
            resp.setMessage(e.getMessage());
        }
        return resp;
    }

    /**
     * 将InputStream写入本地文件
     * @param destination 写入本地目录
     * @param input 输入流
     * @throws IOException IOException
     */
    public static void writeToLocal(String destination, InputStream input)
            throws IOException {
        int index;
        byte[] bytes = new byte[1024];
        FileOutputStream downloadFile = new FileOutputStream(destination);
        while ((index = input.read(bytes)) != -1) {
            downloadFile.write(bytes, 0, index);
            downloadFile.flush();
        }
        input.close();
        downloadFile.close();
    }

    public static void main(String[] args) throws Exception {
        EncrypDES encrypDES = new EncrypDES();
        String a = encrypDES.encrypt("dasrqwe");
        System.out.println(a);
        String b = encrypDES.decrypt(a);
        System.out.println(b);
    }
}
